#ifndef RL_PMS9103M_H
#define RL_PMS9103M_H

#include <Arduino.h>
//#include <HardwareSerial.h>

#include <SoftwareSerial.h>


#define foreach(x)  for(int i=0,row = x[i],size = sizeof(x)/sizeof(x[0]);i < size;row=x[++i])

#define PMS_HEAD1               0x42
#define PMS_HEAD2               0x4d



/* CMD parameters */
#define PMS_CMD_READ            0xe2
//only works in passive mode

#define PMS_CMD_MODE            0xe1
#define PMS_CMD_MODE_PASSIVE    0x00
#define PASSIVE                 0x00
#define PMS_CMD_MODE_ACTIVE     0x01
#define ACTIVE                  0x01
#define PMS_CMD_SLEEP           0xe4
#define PMS_CMD_SLEEP_SLEEP     0x00
#define PMS_CMD_SLEEP_WAKEUP    0x01

struct PMS5003T_DATA {
    uint8_t SIG_1;
    uint8_t SIG_2;
    uint16_t DATA_LENGTH;
    
    //
    // Standard Particles, CF=1
    //
    uint16_t PM_SP_UG_1_0;
    uint16_t PM_SP_UG_2_5;
    uint16_t PM_SP_UG_10_0;

    //
    // Atmospheric environment
    //
    uint16_t PM_AE_UG_1_0;
    uint16_t PM_AE_UG_2_5;
    uint16_t PM_AE_UG_10_0;
    
    uint16_t PM_NUM_0_3;
    uint16_t PM_NUM_0_5;
    uint16_t PM_NUM_1_0;
    uint16_t PM_NUM_2_5;
    uint16_t PM_NUM_5_0;
    uint16_t PM_NUM_10_0;

    uint8_t ERRCODE;
    uint8_t VERCODE;
    
    uint16_t CHECKSUM;
};

/* class */


class PMS9103M : public SoftwareSerial {
    public:
        unsigned int data[20];
        int LastErr;
        //Setup  
        //PMS9103M(int uart_nr) : HardwareSerial(uart_nr){} ;
        PMS9103M(short rxPin, short txPin) :  SoftwareSerial(rxPin,txPin) { };
        void sleep();
        void wakeUp();
        void setMode(byte);
        void request();
        PMS5003T_DATA* readPms();
        int getData(int type);

      
    private:
        byte Packet[5] = {0x42, 0x4d, 0,};
        uint8_t Buff[32];

  
        unsigned int LRC = 0;
        void send(byte, byte, byte);

        PMS5003T_DATA* Pd;
};


#endif
